  /******************************************************************************
  * @file    PT32X005_i2c.c
  * @author  应用开发团队
  * @version V1.1.0
  * @date    2020/1/27
  * @brief    This file provides firmware functions to manage the following
  *          functionalities of the Inter-Integrated circuit (I2C):
  *           + Initialization and Configuration
  *           + Communications handling
  *           + I2C registers management
  *           + Data transfers management
  *           + Interrupts and flags management
  *
  ******************************************************************************
  * @attention
  *
  *
  *****************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "PT32X005_i2c.h"

/** @defgroup I2C
  * @brief I2C driver modules
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/


/**
  * @brief  Initializes the I2Cx peripheral according to the specified
  *            parameters in the I2C_InitStruct.
  * @param  I2Cx: select the I2C peripheral.
  * @param  I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
  *               contains the configuration information for the specified I2C peripheral.
  * @retval None
  */
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
{
	u32 tmpreg =0;
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_I2C_ADDR_VAL(I2C_InitStruct->I2C_ADDR_VAL));
	assert_param(IS_I2C_ACK_SEL(I2C_InitStruct->I2C_ACK_SEL));
	assert_param(IS_I2C_BR_VAL(I2C_InitStruct->I2C_BR_VAL));
	assert_param(IS_I2C_BC_SEL(I2C_InitStruct->I2C_BC_SEL));
	/* Disable I2Cx Peripheral */
	I2Cx->CCR = I2C_CCR_MASK;
	/*---------------------------- I2Cx OAR Configuration ---------------------*/
	/* I2Cx BroadCast Configuration */
	/* I2Cx Address Configuration */
	tmpreg = (u32)(((I2C_InitStruct->I2C_ADDR_VAL) << 0x01) | (I2C_InitStruct->I2C_BC_SEL));
	/* Write to I2Cx OAR */
	I2Cx->OAR = tmpreg;

	/*---------------------------- I2Cx ACK Configuration ----------------------*/
	/* I2Cx ACK Configuration */
	/* I2Cx BR Configuration */
	tmpreg =  (u32)((I2C_InitStruct->I2C_ACK_SEL) | (((I2C_InitStruct->I2C_BR_VAL/4)-1) << 16));
	I2Cx->CR = tmpreg;
}

/**
  * @brief  Fills each I2C_InitStruct member with its default value.
  * @param  I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized.
  * @retval None
  */
void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)
{
	/*---------------- Reset I2C init structure parameters values --------------*/
	/* Initialize the I2C_OwnAddress1 member */
	I2C_InitStruct->I2C_ADDR_VAL = 0;
	/* Initialize the I2C_ACK_SEL member */
	I2C_InitStruct->I2C_ACK_SEL = DISABLE;
	/* Initialize the  Frequency division factor when pclk=24000000 member SCLK=100000 */
	I2C_InitStruct->I2C_BR_VAL = 192;
}

/**
  * @brief  Enables or disables the specified I2C peripheral.
  * @param  I2Cx: select the I2C peripheral.
  * @param  NewState: new state of the I2Cx peripheral.
  *               @arg   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		/* Enable the selected I2C peripheral */
		I2Cx->CR |= I2C_CR_PE;
	}
	else
	{
		/* Disable the selected I2C peripheral */
		I2Cx->CCR |= I2C_CCR_PE;
	}
}


/**
  * @brief  Enables or disables the I2C general call mode.
  * @param  I2Cx: select the I2C peripheral.
  * @param  NewState: new state of the I2C general call mode.
  *               @arg   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void I2C_BroadcastConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		/* Enable general call mode */
		I2Cx->OAR |= I2C_OAR_BC;
	}
	else
	{
		/* Disable general call mode */
		I2Cx->OAR &= (u32)~((u32)I2C_OAR_BC);
	}
}


/**
  * @brief  Generates I2Cx communication START condition.
  * @param  I2Cx: select the I2C peripheral.
  * @param  NewState: new state of the I2C START condition generation.
  *               @arg   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */

void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		/* Generate a START condition */
		I2Cx->CCR |= I2C_CCR_SI;
		I2Cx->CR |= I2C_CR_STAR;
	}
	else
	{
		/* Disable the START condition generation */
		I2Cx->CCR |= I2C_CCR_STAR|I2C_CCR_SI;
	}
}

/**
  * @brief  Generates I2Cx communication STOP condition.
  * @param  I2Cx: select the I2C peripheral.
  * @param  NewState: new state of the I2C STOP condition generation.
  *               @arg   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		/* Generate a STOP condition */
		I2Cx->CCR |= I2C_CCR_SI;
		I2Cx->CR |= I2C_CR_STOP;
	}
	else
	{
		/* Disable the STOP condition generation */
		I2Cx->CCR |= I2C_CCR_SI | I2C_CR_STOP;
	}
}


/**
  * @brief  Generates I2C communication Acknowledge.
  * @param  I2Cx: select the I2C peripheral.
  * @param  NewState: new state of the Acknowledge.
  *               @arg   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		/* Enable ACK generation */
		I2Cx->CCR |= I2C_CCR_SI;
		I2Cx->CR |= I2C_CR_ACK;
	}
	else
	{
		/* Enable NACK generation */
		I2Cx->CCR |= I2C_CCR_SI | I2C_CCR_ACK;
		I2Cx->CR &= ~I2C_CR_ACK;
	}
}


/**
  * @brief  Sends a data byte through the I2Cx peripheral.
  * @param  I2Cx: select the I2C peripheral.
  * @param  Data: Byte to be transmitted..
  * @retval None
  */
void I2C_SendData(I2C_TypeDef* I2Cx, u8 Data)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	/* Write in the DR register the data to be sent */
	I2Cx->DR = (u8)Data;
	I2Cx->CCR |= I2C_CCR_SI;
}
/**
  * @brief  Sends a data/addr byte through the I2Cx peripheral, then clear STA bit
  * @param  I2Cx: select the I2C peripheral.
  * @param  Data: Byte to be transmitted..
  * @retval None
  */
void I2C_SendAddr(I2C_TypeDef* I2Cx, u8 Data)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	/* Write in the DR register the data to be sent */
	I2Cx->DR = (u8)Data;
	I2Cx->CCR |= I2C_CCR_SI | I2C_CCR_STAR;
}


/**
  * @brief  Returns the most recent received data by the I2Cx peripheral.
  * @param  I2Cx: select the I2C peripheral.
  * @retval The value of the received data.
  */
u8 I2C_ReceiveData(I2C_TypeDef* I2Cx)
{
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	/* Return the data in the DR register */
	return (I2Cx->DR);
}



/**
  * @brief  Checks whether the specified I2C flag is set or not.
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
  * @param  I2C_FLAG: specifies the flag to check.
  *               This parameter can be one of the following values:
  *               @arg I2C_Stop 				总线上出现一个停止信号
  *               @arg I2C_StartOk 			起始信号发送完毕
  *               @arg I2C_ReStartOk 			重复起始信号发送完毕
  *               @arg I2C_MAS_GetAck_W 		主机， 地址字发送完毕， 收到 ACK
  *               @arg I2C_MAS_GetNack_W 	主机， 地址字发送完毕， 收到 NACK
  *               @arg I2C_MDS_GetAck 		主机， 数据字发送完毕， 收到 ACK
  *               @arg I2C_MDS_GetNack 		主机， 数据字发送完毕， 收到 NACK
  *               @arg I2C_MAL  				主机， 总线仲裁失败
  *               @arg I2C_MAS_SendAck_R 	主机， 地址字发送完毕， 回送 ACK
  *               @arg I2C_MAS_SendNack_R 	主机， 地址字发送完毕， 回送 NACK
  *               @arg I2C_MDG_SendAck 		主机， 数据字接收完毕， 回送 ACK
  *               @arg I2C_MDG_SendNack 		主机， 数据字接收完毕， 回送 NACK

  *               @arg I2C_SAG_SendAck_W 	从机， 地址字接收完毕， 回送 ACK
  *               @arg I2C_SAL_AG_SendAck_W 	从机，总线仲裁失败转化的从机， 地址字接收完毕， 回送 ACK
  *               @arg I2C_SBCAG_SendAck 	从机，广播地址字接收完毕， 回送 ACK
  *               @arg I2C_SAL_BCAG_SendAck 	从机，总线仲裁失败转化的从机，广播地址字接收完毕， 回送 ACK
  *               @arg I2C_SDG_SendAck 		从机， 数据字接收完毕， 回送 ACK
  *               @arg I2C_SDG_SendNack 		从机， 数据字接收完毕， 回送 NACK
  *               @arg I2C_SBCDG_SendAck 	从机， 广播数据字接收完毕， 回送 ACK
  *               @arg I2C_SBCDG_SendNack 	从机， 广播数据字接收完毕， 回送 NACK
  *               @arg I2C_SDG_GSRS 			从机， 数据字接收完毕， 接收到停止信号或重复起始信号
  *               @arg I2C_SAG_SendAck_R 	从机， 地址字接收完毕， 回送 ACK
  *               @arg I2C_SAL_AG_SendAck_R 	从机， 主机总线仲裁失败转化的从机,地址字接收完毕， 回送 ACK
  *               @arg I2C_SDS_ReadAck 		从机， 数据字发送完毕， 收到 ACK
  *               @arg I2C_SDS_ReadNack 		从机， 数据字发送完毕， 收到 NACK
  *               @arg I2C_SDSSA_GSRS 		从机， 数据字接收完毕， 回送 ACK 后、接收到停止信号或重复起始信号
  *               @arg I2C_IDLE 				总线空闲
  * @retval The new state of I2C_FLAG (SET or RESET).
  */
FlagStatus I2C_GetStatus(I2C_TypeDef* I2Cx, u16 I2C_FLAG)
{
	FlagStatus bitstatus = RESET;
	/* Check the parameters */
	assert_param(IS_I2C_ALL_PERIPH(I2Cx));
	assert_param(IS_I2C_SR_SEL(I2C_FLAG));
	I2C_FLAG=(I2C_FLAG<<3);
	if (I2Cx->SR  == I2C_FLAG)
	{
		bitstatus = SET;
	}
	else
	{
		bitstatus = RESET;
	}
	return bitstatus;
}


/**
  * @}
  */

